package pku.tcs.wsc.parser;

import java.util.List;
import java.io.FileInputStream;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import pku.tcs.wsc.service.ServicePool;

/**
 * @brief WSLA parser, gets qos information from wsla file
 * @author Lilei
 */
public class WSLAParser {
	/**the services repository passed as parameter between parsers*/
	private ServicePool servicePool;
	/**the wsla file path*/
	private String wslaFilePath;
	
	/**
	 * Get the first child element by name
	 * @param father
	 * @param name
	 * @return
	 */
	protected Element getFirstChildByName(Element father,String name){
		if(father==null||name==null)
			return null;
		List children = father.getChildren();
		for(Element ele:(List<Element>)children){
			if(ele.getName().equals(name))
				return ele;
		}
		return null;
	}
	
	public WSLAParser(String filePath,ServicePool pool){
		servicePool = pool;
		wslaFilePath = filePath;
	}
	
	/**
	 * @brief parse wsla file 
	 * 
	 * The structure of wsla (web service level agreements) file is like:
	 * 	
	 * 	1	xml definitions...
	 * 	2	parties					(we can ignore it)
	 * 	3	ServiceDefinition		(irrelevant for the wsc)
	 * 		...
	 * 	n	ServiceDefinition		(irrelevant for the wsc)
	 * 	n+1	Obligations				(that's it~,we get qos from this node and its children)
	 * 
	 * Obligation node has very succinct structure, an example is listed below:
	 * 
	 * 	Obligations
	 * 		1		ServiceLevelObjective	Response Time qos of the first service 
	 * 		2		ServiceLevelObjective	Throughput qos of the first service
	 * 				...	
	 * 		2n-1	ServiceLevelObjective	Response Time qos of the nth service
	 * 		2n		ServiceLevelObjective	Throughput qos of the nth service
	 */
	public void parse(){
		
		/**first initialize the dom parser...*/
		SAXBuilder sb = new SAXBuilder();
		Document   doc = null;
		try {
			doc = sb.build(new FileInputStream(wslaFilePath));
		} catch (Exception e) {
			e.printStackTrace();
			}
		
		/**now we get the root element of qos informations, that is, the element with
		 * name "Obligations"
		 **/
		Element obligations = getFirstChildByName(doc.getRootElement(), "Obligations");
		List qosList = obligations.getChildren();
		
		String responseServiceId;
		String throughputServiceId;
		String responseQos;
		String throughputQos;
		
		for(int i=0;i<qosList.size();i+=2){
			
			Element responseElement = (Element) qosList.get(i);
			Element throughputElement = (Element) qosList.get(i+1);
			
			
			Element expression = getFirstChildByName(responseElement, "Expression");
			Element predicate =  getFirstChildByName(expression, "Predicate");
			responseServiceId = getFirstChildByName(predicate,"SLAParameter").getText();
			responseServiceId = responseServiceId.replace("SLAParameterResponsetimeserv", "");
		
			
			Element throughputExpression = getFirstChildByName(throughputElement, "Expression");
			Element throughputPredicate =  getFirstChildByName(throughputExpression, "Predicate");
			throughputServiceId = getFirstChildByName(throughputPredicate,"SLAParameter").getText();
			throughputServiceId = throughputServiceId.replace("SLAParameterThroughputserv", "");
			
			/**the two id must equal with each other*/
			assert(responseServiceId.equals(throughputServiceId));
			
			responseQos = getFirstChildByName(predicate,"Value").getText();
			throughputQos = getFirstChildByName(throughputPredicate,"Value").getText();
			
			try {
				servicePool.addServiceQos(responseServiceId, Long.parseLong(responseQos), Float.parseFloat(throughputQos));
			} catch (NumberFormatException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args){
		ServicePool sp = new ServicePool();
		WSLAParser parser = new WSLAParser("./data/Servicelevelagreements.wsla",sp);
		parser.parse();
	}
	
}
